package com.xiaoge.testproxy;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.NameMatchMethodPointcut;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.expression.spel.ast.NullLiteral;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.lang.reflect.Method;

/**
 * TODO
 *
 * @author <a href="mailto:1330137071@qq.com">Zhang Xiao</a>
 * @since
 */
//@Configuration
public class TestDefaultAdvisorAutoProxyCreator {

	@Bean
	public DefaultPointcutAdvisor defaultPointcutAdvisor() {
		NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
		// todo 切面方法名称为test, 只要是test方法都会被切
		pointcut.addMethodName("test");
		DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();
		// todo 指定代理的方案
		defaultPointcutAdvisor.setPointcut(pointcut);
//		defaultPointcutAdvisor.setPointcut(new Pointcut() {
//			@Override
//			public ClassFilter getClassFilter() {
//				return new ClassFilter() {
//					@Override
//					public boolean matches(Class<?> clazz) {
//						// todo 根据类代理
//						return false;
//					}
//				};
//			}
//
//			@Override
//			public MethodMatcher getMethodMatcher() {
//				return new MethodMatcher() {
//					@Override
//					public boolean matches(Method method, Class<?> targetClass) {
//						// todo 根据方法代理
//						return false;
//					}
//
//					@Override
//					public boolean isRuntime() {
//						return false;
//					}
//
//					@Override
//					public boolean matches(Method method, Class<?> targetClass, Object... args) {
//						return false;
//					}
//				};
//			}
//		});
		// todo 指定代理的逻辑
		defaultPointcutAdvisor.setAdvice(new MethodInterceptor() {
			@Nullable
			@Override
			public Object invoke(@Nonnull MethodInvocation invocation) throws Throwable {
				System.out.println(".....before.....");
				Object result = invocation.proceed();  // target调用的方法, 例如target.test()
				System.out.println(".....after.....");
				return result;
			}
		});
		return defaultPointcutAdvisor;
	}

	/**
	 * todo 它去创建bean的时候只要发现我们上面定义的满足条件, 它就会去动态代理
	 * @return
	 */
	@Bean
	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
		DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
		return defaultAdvisorAutoProxyCreator;
	}

}
